package dst.ass1.jpa.model.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import dst.ass1.jpa.model.IExpert;
import dst.ass1.jpa.model.ITaskForce;
import dst.ass1.jpa.model.ITaskWorker;
import dst.ass1.jpa.model.IWorkPlatform;

@Entity
public class TaskForce implements ITaskForce{
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO )
	private Long id;
	
	@Column(unique = true)
	private String name;
	
	private Date lastMeeting;
	
	private Date nextMeeting;
	
	@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, targetEntity = TaskForce.class, fetch=FetchType.LAZY)  //to-star(collection) props are loaded lazily (as the number of items may well be very large
    @JoinTable(name = "composed_of",
               joinColumns = @JoinColumn(name = "partOf_id", referencedColumnName = "id"),
               inverseJoinColumns = @JoinColumn(name = "composedOf_id", referencedColumnName = "id"))
	private List<ITaskForce> composedOf;
	
	@ManyToMany(targetEntity = TaskForce.class, mappedBy = "composedOf", fetch=FetchType.LAZY) //to-star(collection) props are loaded lazily (as the number of items may well be very large
	private List<ITaskForce> partOf;

	@OneToMany(cascade=CascadeType.ALL, targetEntity = TaskWorker.class, mappedBy="taskForce", fetch=FetchType.LAZY)  //to-star(collection) props are loaded lazily (as the number of items may well be very large)
	private List<ITaskWorker> taskWorker;
	
	@ManyToOne(targetEntity=Expert.class,cascade = { CascadeType.PERSIST, CascadeType.MERGE },fetch=FetchType.EAGER) //to-one properties are loaded eagerly (as loading them is cheap)
	private IExpert expert;
	
	@ManyToOne(targetEntity = WorkPlatform.class, optional = false, cascade = { CascadeType.PERSIST, CascadeType.MERGE },fetch=FetchType.EAGER) //to-one properties are loaded eagerly (as loading them is cheap)
	private IWorkPlatform workPlatform;
	
	
	private final static Logger LOGGER = Logger.getLogger(TaskForce.class.getName());
	
	public TaskForce(){
		this.composedOf= new ArrayList<ITaskForce>();
		this.partOf=new ArrayList<ITaskForce>();
		this.taskWorker=new ArrayList<ITaskWorker>();
	}
	
	
	
	@Override
	public Long getId() {
		return id;
	}
	
	@Override
	public void setId(Long id) {
		this.id = id;
	}
	
	@Override
	public String getName() {
		return name;
	}
	
	@Override
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public Date getLastMeeting() {
		return lastMeeting;
	}
	
	@Override
	public void setLastMeeting(Date lastMeeting) {
		this.lastMeeting = lastMeeting;
	}
	
	@Override
	public Date getNextMeeting() {
		return nextMeeting;
	}
	
	@Override
	public void setNextMeeting(Date nextMeeting) {
		this.nextMeeting = nextMeeting;
	}
	
	@Override
	public List<ITaskForce> getComposedOf() {
		return composedOf;
	}
	
	@Override
	public void setComposedOf(List<ITaskForce> composedOf) {
		this.composedOf = composedOf;
	}
	
	@Override
	public List<ITaskForce> getPartOf() {
		return partOf;
	}
	
	@Override
	public void setPartOf(List<ITaskForce> partOf) {
		this.partOf = partOf;
	}
	
	@Override
	public List<ITaskWorker> getTaskWorkers() {
		return taskWorker;
	}
	
	@Override
	public void setTaskWorkers(List<ITaskWorker> worker) {
		this.taskWorker = worker;
	}
	
	@Override
	public IExpert getExpert() {
		return expert;
	}
	
	@Override
	public void setExpert(IExpert expert) {
		this.expert = expert;
	}
	
	@Override
	public IWorkPlatform getWorkPlatform() {
		return workPlatform;
	}
	
	@Override
	public void setWorkPlatform(IWorkPlatform platform) {
		this.workPlatform = platform;
	}
	
	@Override
	public void addComposedOf(ITaskForce o) {
		if(this.composedOf!=null){
			this.composedOf.add(o);
		}
		else{
			LOGGER.info("TaskForce.List<ITaskForce> was null");
		}
	}
	
	@Override
	public void addPartOf(ITaskForce o) {
		if(this.partOf!=null){
			this.partOf.add(o);
		}
		else{
			LOGGER.info("TaskForce.List<ITaskForce> was null");
		}		
	}

	@Override
	public void addTaskWorker(ITaskWorker worker) {
		if(this.taskWorker!=null){
			this.taskWorker.add(worker);
		}
		else{
			LOGGER.info("TaskForce.List<ITaskForce> was null");
		}		
	}


	

	

}
